/**
 * 获取指定子系统当前用户可访问的菜单树
 */
 (function ({ UID, ID }, headers) {
  // 验证用户
  if (!UID) throw Error("无效会话");

  // 加载被授权的菜单项
  let { rows } = A.db.execute(A.card('B.用户').连接名称, "SELECT B.CD_ID FROM B_YHJS A, B_JSCD B WHERE A.JS_ID=B.JS_ID AND A.YH_ID=? AND B.ZXT_ID=? UNION SELECT B.CD_ID FROM B_YHJG A, B_JGCD B WHERE A.JG_ID=B.JG_ID AND A.YH_ID=? AND B.ZXT_ID=? UNION SELECT B.CD_ID FROM B_YHGW A, B_GWCD B WHERE A.GW_ID=B.GW_ID AND A.YH_ID=? AND B.ZXT_ID=? UNION SELECT B.CD_ID FROM B_YHZW A, B_ZWCD B WHERE A.ZW_ID=B.ZW_ID AND A.YH_ID=? AND B.ZXT_ID=?", [UID, ID, UID, ID, UID, ID, UID, ID]);
  let cd_ids = rows.map(r => r.CD_ID);

  // 加载授权菜单和所有子菜单
  let { Rows: items } = A.job.TreeR({
    UID,
    Card: '子系统菜单',
    Model: ['名称', '上级', '页面', '序号'],
    Filter: [['ID', 'in', cd_ids]],
    Order: { 序号: 'asc' },
    Parent: '上级',
  });

  const root = [];
  const map = new Map();
  const asc = (a, b) => a.序号 - b.序号;
  // 扩展到根节点(最多三级, 因此不需要递归)
  items.forEach(item => {
    map.set(item.ID, item);
    if (item.上级) {
      if (map.has(item.上级)) {
        map.get(item.上级).children.push(item);
        map.get(item.上级).children.sort(asc);
      } else {
        let [parent] = A.job.CardR(UID, '子系统菜单', ['名称', '上级', '页面', '序号'], [['ID', '=', item.上级]]).Rows;
        if (!parent) return; // 上级不存在的时候, 直接忽略掉整个分支
        map.set(parent.ID, parent);
        parent.children = [item];

        if (parent.上级) {
          if (map.has(parent.上级)) {
            map.get(parent.上级).children.push(parent);
            map.get(parent.上级).children.sort(asc);
          } else {
            let [parent_parent] = A.job.CardR(UID, '子系统菜单', ['名称', '上级', '页面', '序号'], [['ID', '=', parent.上级]]).Rows;
            if (!parent_parent) return; // 上级不存在的时候, 直接忽略掉整个分支
            map.set(parent_parent.ID, parent_parent);
            parent_parent.children = [parent];
            root.push(parent_parent);
          }
        } else {
          root.push(parent);
        }
      }
    } else {
      root.push(item);
    }
  });

  root.sort(asc);
  return root;
});